package com.dy.yunying.biz.service.sign.impl;

import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.dto.sign.SignActivityPrizeDto;
import com.dy.yunying.api.entity.sign.SignActivityPrize;
import com.dy.yunying.api.entity.sign.SignPrizeGoods;
import com.dy.yunying.api.vo.sign.GoodsVO;
import com.dy.yunying.biz.dao.ads.sign.SignActivityPrizeMapper;
import com.dy.yunying.biz.service.sign.SignActivityPrizeService;
import com.dy.yunying.biz.service.sign.SignPrizeGoodsService;
import com.dy.yunying.biz.service.sign.SignTaskConfigService;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.common.core.util.DateUtil;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 签到活动奖品表
 *
 * @author chengang
 * @version 2021-12-01 10:14:16
 * table: sign_activity_prize
 */
@Log4j2
@Service("signActivityPrizeService")
@RequiredArgsConstructor
public class SignActivityPrizeServiceImpl extends ServiceImpl<SignActivityPrizeMapper, SignActivityPrize> implements SignActivityPrizeService {

	private final SignPrizeGoodsService signPrizeGoodsService;
	private final SignTaskConfigService signTaskConfigService;

	/**
	 * 获取分页列表
	 *
	 * @param record
	 * @return
	 */
	@Transactional(readOnly = true, value = "adsTransactionManager", rollbackFor = Exception.class)
	@Override
	public Page<SignActivityPrize> getPage(SignActivityPrizeDto record) {
		final LambdaQueryWrapper<SignActivityPrize> queryWrapper = Wrappers.<SignActivityPrize>lambdaQuery()
				.and(wrapper -> wrapper.eq(SignActivityPrize::getActivityId, record.getActivityId()))
				.and(StringUtils.isNotBlank(record.getName()), wrapper -> wrapper.like(SignActivityPrize::getName, record.getName()))
				.and(wrapper -> wrapper.eq(SignActivityPrize::getDeleted, NumberUtils.INTEGER_ZERO))
				.orderByAsc(SignActivityPrize::getReceiveSn);
		final Page<SignActivityPrize> listPage = this.page(new Page<>(record.getCurrent(), record.getSize()), queryWrapper);
		// 遍历奖品列表，填充领取相关数据
		final List<SignActivityPrize> activityPrizeList = listPage.getRecords();
		if (CollectionUtils.isEmpty(listPage.getRecords())) {
			return listPage;
		}
		final Set<Long> prizeIdSet = activityPrizeList.stream().map(SignActivityPrize::getId).collect(Collectors.toSet());
		final Map<Long, SignActivityPrize> prizeMapping = this.getBaseMapper().selectReceiveCountList(prizeIdSet).stream().filter(e -> Objects.nonNull(e.getId())).collect(Collectors.toMap(SignActivityPrize::getId, e -> e, (k1, k2) -> k1));
		for (SignActivityPrize prize : activityPrizeList) {
			final SignActivityPrize receive = prizeMapping.get(prize.getId());
			if (null != receive) {
				prize.setGiftTotalNum(receive.getGiftTotalNum());
				prize.setGiftUseNum(receive.getGiftUseNum());
				prize.setSendNum(receive.getSendNum());
				prize.setGoodsList(receive.getGoodsList());
			}
		}
		return listPage;
	}

	@Transactional(value = "adsTransactionManager", rollbackFor = Exception.class)
	@Override
	public R editPrize(SignActivityPrizeDto dto) {
		Map<String,String> result = new HashMap<>();
		String info = "操作成功";
		if (dto.getType().intValue() == 1) {
			// 礼包唯一码
			if ("1".equals(dto.getGiftType())) {
				try {
					//校验礼包码文件并保存hb_gift_bag
					Pair<Integer, Integer> giftBag = signTaskConfigService.saveSignGiftBag(dto.getFile(), 3, dto.getId());
					info = "操作成功，礼包码上传成功：" + giftBag.getRight() + " 个，重复无效过滤：" + (giftBag.getLeft() - giftBag.getRight()) + " 个";
				} catch (IllegalArgumentException e) {
					return R.failed(e.getMessage());
				}
			}
			this.handlePrizeGoods(dto);
		}

		int type = ObjectUtils.defaultIfNull(dto.getType(), -1);
		int expiryType = ObjectUtils.defaultIfNull(dto.getExpiryType(), -1);
		int currencyType = ObjectUtils.defaultIfNull(dto.getCurrencyType(), -1);
		int currencyExpireType = ObjectUtils.defaultIfNull(dto.getCurrencyExpireType(), -1);
		if(StringUtils.isNotBlank(dto.getEndTime())){
			try{
				dto.setEndTime(DateUtils.format(DateUtils.parseDate(dto.getEndTime()+" 23:59:59"),"yyyy-MM-dd HH:mm:ss"));
			}catch (ParseException p){
				log.error("editPrize parseTime  is error",p);
			}
		}
		//更新主表sign_activity_prize
		this.update(Wrappers.<SignActivityPrize>lambdaUpdate()
				.eq(SignActivityPrize::getId, dto.getId())
				.set(SignActivityPrize::getName, dto.getName())
				.set(SignActivityPrize::getType, dto.getType())
				.set(SignActivityPrize::getUpdateId, dto.getUpdateId())
				.set(type == 1, SignActivityPrize::getGiftType, dto.getGiftType())
				.set(type == 1, SignActivityPrize::getGiftCode, dto.getGiftCode())
				.set(type == 1, SignActivityPrize::getGiftAmount, dto.getGiftAmount())
				.set(type == 2, SignActivityPrize::getCdkName, dto.getCdkName())
				.set(type == 2, SignActivityPrize::getCdkAmount, dto.getCdkAmount())
				.set(type == 2, SignActivityPrize::getCdkLimitAmount, dto.getCdkLimitAmount())
				.set(type == 2, SignActivityPrize::getExpiryType, dto.getExpiryType())
				.set(dto.getType().intValue() == 2, SignActivityPrize::getCdkLimitType, dto.getCdkLimitType())
				.set(type == 2 && expiryType == 1, SignActivityPrize::getStartTime, dto.getStartTime())
				.set(type == 2 && expiryType == 1, SignActivityPrize::getEndTime, dto.getEndTime())
				.set(type == 2 && expiryType == 2, SignActivityPrize::getDays, dto.getDays())
				.set(type == 3, SignActivityPrize::getCurrencyAmount, dto.getCurrencyAmount())
				.set(type == 3, SignActivityPrize::getCurrencyType, dto.getCurrencyType())
				.set(type == 3 && currencyType == 2, SignActivityPrize::getCurrencyExpireType, dto.getCurrencyExpireType())
				.set(type == 3 && currencyExpireType == 1, SignActivityPrize::getCurrencyExpireTime, dto.getCurrencyExpireTime())
				.set(type == 3 && currencyExpireType == 2, SignActivityPrize::getCurrencyExpireDays, dto.getCurrencyExpireDays())
		);
		result.put("info",info);
		return R.ok(result);
	}

	private void handlePrizeGoods(SignActivityPrizeDto dto) {

		List<GoodsVO> goodsList = JSON.parseArray(dto.getGoodsJson(), GoodsVO.class);
		//更新关联表sign_prize_goods 游戏上线后只能修改礼包码
		List<SignPrizeGoods> prizeGoodsList = Lists.newArrayList();
		goodsList.forEach(goods -> {
			SignPrizeGoods prizeGoods = new SignPrizeGoods();
			prizeGoods.setCreateId(dto.getCreateId());
			prizeGoods.setUpdateId(dto.getUpdateId());
			prizeGoods.setGoodsId(goods.getGoodsId());
			prizeGoods.setNum(goods.getGoodsCount());
			prizeGoods.setPrizeId(dto.getId());

			prizeGoodsList.add(prizeGoods);
		});

		//先删除后插入
		signPrizeGoodsService.update(Wrappers.<SignPrizeGoods>lambdaUpdate()
				.eq(SignPrizeGoods::getPrizeId, dto.getId())
				.set(SignPrizeGoods::getDeleted, 1));
		signPrizeGoodsService.saveBatch(prizeGoodsList);
	}
}


